using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace outputLib
{
	public sealed class output
	{
		string interestingLine;
		string[] bits;
		string path;
		string newpath;
		int nRuns;
		int coordRuns;
		int cutOff;
		int nSuccess;
		int n;
		bool coordFile;

		public output(string pth, int nruns, int cutoff, int cruns)
		{
			path = pth;
			newpath = Path.GetDirectoryName(path);
			nRuns = nruns;
			coordRuns = cruns;
			cutOff = cutoff;
		}

		public void HMC()
		{
			StreamReader sr = new StreamReader(path);
			StreamWriter sw = new StreamWriter(newpath + "\\results.txt", false);
            //StreamWriter swn = new StreamWriter(newpath + "\\minima.txt", false);
			string line;
            //List<double> min = new List<double>();
            //List<double[]> m = new List<double[]>();
            sw.WriteLine("Alg: HMC");
            sw.WriteLine();

			line = sr.ReadLine();

			/*  structure is: 
				Seed               bits[0]
				Temperature start  bits[1]
				Temperature step   bits[2]
				Temperature end    bits[3]
				metropolis         bits[4]
				N_md               bits[5]
				N_mc               bits[6]
				N_runs             bits[7]
				N                  bits[8]
			    without			   bits[9]
			    with			   bits[10]
			    evaluations		   bits[11]
			    distance		   bits[12]
			    runnumber          bits[13]
			* */

			while (!sr.EndOfStream)
			{
                //min.Clear();
                //m.Clear();
				nSuccess = 0;

				for (int i = 1; i <= nRuns; i++)
				{
					interestingLine = sr.ReadLine();
					bits = interestingLine.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries);

					if (bits.Length == 14)
					{
                        //min.Add(double.Parse(bits[10]));

						if ((double.Parse(bits[10])) < cutOff)
						{
							nSuccess++;
						}
					}
					else
					{
						throw new Exception("Length of bits isn't correct");
					}
				}

                /*min.Sort();

                int j = 0;
                int inew = 0;
                int frequency = 1;

                do
                {
                    double[] dtemp = new double[2];
                    j += 1;
                    frequency = 1;
                    dtemp[0] = min[inew];

                    while (j < min.Count && min[inew] == min[j])
                    {
                        frequency++;
                        j++;
                    }
                    inew = j;

                    dtemp[1] = frequency;
                    m.Add(dtemp);
                } while (inew < (min.Count - 1));

                if (min[min.Count - 2] != min[min.Count - 1])
                {
                    double[] dtemp = new double[2];
                    dtemp[0] = min[min.Count - 1];
                    dtemp[1] = 1;

                    m.Add(dtemp);
                }*/

				string tempStart = bits[1];
				string metropolis = bits[4];
				string N_md = bits[5];
				string N_mc = bits[6];

				sw.WriteLine(tempStart + "\t" + metropolis + "\t" + N_md + "\t" + N_mc + "\t" + nSuccess);
			}

            /*swn.WriteLine("Unique Minima: " + m.Count);
            swn.WriteLine("Func Val" + "\t" + "Frequency");
            swn.WriteLine();
            foreach (double[] d in m)
            {
                swn.WriteLine(d[0] + "\t\t" + d[1]);
            }

            swn.WriteLine();
            swn.WriteLine();*/

			sw.Close();
            //swn.Close();
			sr.Close();
		}

		public void MRSA()
		{
			StreamReader sr = new StreamReader(path);
			StreamWriter sw = new StreamWriter(newpath + "\\results.txt", false);
            //StreamWriter swn = new StreamWriter(newpath + "\\minima.txt", false);
            string line;
            //List<double> min = new List<double>();
            //List<double[]> m = new List<double[]>();
            sw.WriteLine("Alg: MRSA");
            sw.WriteLine();

			line = sr.ReadLine();

			/*  structure is: 
				Seed               bits[0]
				Temperature start  bits[1]
				Temperature step   bits[2]
				Temperature end    bits[3]
				metropolis         bits[4]
				N_md               bits[5]
				N_mc               bits[6]
				N_runs             bits[7]
				N                  bits[8]
				NMin			   bits[9]
			    without			   bits[10]
			    with			   bits[11]
			    bestCont		   bits[12]
			    evaluations		   bits[13]
			    distance		   bits[14]
			    runnumber          bits[15]
			* */

			while (!sr.EndOfStream)
			{
                //min.Clear();
                //m.Clear();
				nSuccess = 0;

				for (int i = 1; i <= nRuns; i++)
				{
					interestingLine = sr.ReadLine();
					bits = interestingLine.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries);

					if (bits.Length == 16)
					{
                        //min.Add(double.Parse(bits[11]));

						if ((double.Parse(bits[11]) < cutOff) || (double.Parse(bits[12]) < cutOff))
						{
							nSuccess++;
						}
					}
					else
					{
						throw new Exception("Length of bits isn't correct");
					}
				}

                /*min.Sort();

                int j = 0;
                int inew = 0;
                int frequency = 1;

                do
                {
                    double[] dtemp = new double[2];
                    j += 1;
                    frequency = 1;
                    dtemp[0] = min[inew];

                    while (j < min.Count && min[inew] == min[j])
                    {
                        frequency++;
                        j++;
                    }
                    inew = j;

                    dtemp[1] = frequency;
                    m.Add(dtemp);
                } while (inew < (min.Count - 1));

                if (min[min.Count - 2] != min[min.Count - 1])
                {
                    double[] dtemp = new double[2];
                    dtemp[0] = min[min.Count - 1];
                    dtemp[1] = 1;

                    m.Add(dtemp);
                }*/

				string tempStart = bits[1];
				string metropolis = bits[4];
				string N_md = bits[5];
				string N_mc = bits[6];

				sw.WriteLine(tempStart + "\t" + metropolis + "\t" + N_md + "\t" + N_mc + "\t" + nSuccess);

                
			}

            /*swn.WriteLine("Unique Minima: " + m.Count);
            swn.WriteLine("Func Val" + "\t" + "Frequency");
            swn.WriteLine();
            foreach (double[] d in m)
            {
                swn.WriteLine(d[0] + "\t\t" + d[1]);
            }

            swn.WriteLine();
            swn.WriteLine();*/

			sw.Close();
            //swn.Close();
			sr.Close();
		}

        public void LSRes()
        {
            StreamReader sr = new StreamReader(path);
            StreamWriter sw = new StreamWriter(newpath + "\\results.txt", false);
            StreamWriter swn = new StreamWriter(newpath + "\\minima.txt", false);
            StreamReader src = null;
            coordFile = false;

            string coordPath = newpath + "\\coords.csv";

            if (File.Exists(coordPath))
            {
                src = new StreamReader(coordPath);
                coordFile = true;
            }
            string line;
            List<Store> store = new List<Store>();
            List<double> min = new List<double>();
            List<double[]> m = new List<double[]>();

            line = sr.ReadLine();
            if (coordFile)
            {
                line = src.ReadLine();
            }

            /*  structure is: 
                Seed               bits[0]
                CGM Tolerance	   bits[1]
                N_runs             bits[2]
                N                  bits[3]
                Before			   bits[4]
                After			   bits[5]
                evaluations		   bits[6]
                distance		   bits[7]
                runnumber          bits[8]
            * */

            while (!sr.EndOfStream)
            {
                store.Clear();
                min.Clear();
                m.Clear();
                nSuccess = 0;
                n = 0;

                for (int i = 1; i <= nRuns; i++)
                {
                    interestingLine = sr.ReadLine();
                    bits = interestingLine.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries);


                    if (bits.Length == 9)
                    {
                        min.Add(double.Parse(bits[5]));

                        if ((double.Parse(bits[5])) < cutOff)
                        {
                            nSuccess += 1;
                            Store s = s = new Store(double.Parse(bits[5]), int.Parse(bits[8]), double.Parse(bits[7]));
                            store.Add(s);

                            if (coordFile)
                            {
                                store[n].Coords = Coord(src, store[n].runnumber.ToString());
                                n++;
                            }
                        }
                    }
                    else
                    {
                        throw new Exception("Length of bits isn't correct");
                    }
                }

                min.Sort();

                int j = 0;
                int inew = 0;
                int frequency = 1;

                do
                {
                    double[] dtemp = new double[2];
                    j += 1;
                    frequency = 1;
                    dtemp[0] = min[inew];

                    while (j < min.Count && min[inew] == min[j])
                    {
                        frequency++;
                        j++;
                    }
                    inew = j;

                    dtemp[1] = frequency;
                    m.Add(dtemp);
                } while (inew < (min.Count - 1));

                if (min[min.Count - 2] != min[min.Count - 1])
                {
                    double[] dtemp = new double[2];
                    dtemp[0] = min[min.Count - 1];
                    dtemp[1] = 1;

                    m.Add(dtemp);
                }

                string toler = bits[1];
                string nruns = nRuns.ToString();

                sw.WriteLine(toler + "\t" + nruns + "\t" + nSuccess);
                sw.WriteLine();

                foreach (Store s in store)
                {
                    sw.Write("\t\t" + s.fval + "\t" + s.runnumber + "\t" + s.distance + "\t");

                    if (coordFile)
                    {
                        for (int i = 0; i < s.coords.Length; i++)
                        {
                            sw.Write(s.coords[i] + "  ");
                        }
                    }

                    sw.WriteLine();
                }

                sw.WriteLine();
                sw.WriteLine();

                
            }

            swn.WriteLine("Unique Minima: " + m.Count);
            swn.WriteLine("Func Val" + "\t" + "Frequency");
            swn.WriteLine();
            foreach (double[] d in m)
            {
                swn.WriteLine(d[0] + "\t\t" + d[1]);
            }

            swn.WriteLine();
            swn.WriteLine();

            sw.Close();
            sr.Close();
            swn.Close();
            if (coordFile)
            {
                src.Close();
            }
        }

		private string[] Coord(StreamReader coord, string runnumber)
		{
			string[] coordinates = null;

			while (true)
			{
				string coordLine = coord.ReadLine();
				if (coordLine.StartsWith(runnumber))
				{
					coordLine = coordLine.Remove(0, runnumber.Length);
					coordinates = coordLine.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries);
					return coordinates;
				}
			}
		}

		
	}
}
